package com.chart.chart.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chart.chart.domian.ChartVouchers;
import com.chart.chart.domian.req.VerifiedReq;
import com.chart.chart.mapper.ChartVouchersMapper;
import com.chart.chart.service.IChartVouchersService;


import com.chart.common.core.domain.AjaxResult;
import com.chart.common.core.domain.entity.SysUser;
import com.chart.common.core.domain.model.LoginUser;
import com.chart.common.core.redis.RedisCache;
import com.chart.common.utils.SecurityUtils;
import com.chart.constant.VouchersType;
import com.chart.system.domain.SysUserOrder;
import com.chart.system.mapper.SysUserMapper;
import com.chart.system.mapper.SysUserOrderMapper;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Service
public class ChartVouchersServiceImpl extends ServiceImpl<ChartVouchersMapper, ChartVouchers> implements IChartVouchersService {

    @Resource
    private SysUserOrderMapper userOrderMapper;

    @Resource
    private SysUserMapper userMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ChartVouchersMapper chartVouchersMapper;


    @Override
    @Transactional
    public String generate(Integer type) {
        String vouchers = vouchersGenerator();
        LocalDateTime now = LocalDateTimeUtil.now();
        String expiredTime = now.plusMonths(3).toString();
        ChartVouchers chartVouchers = ChartVouchers.builder().type(type)
                .status(VouchersType.UN_USED.getValue())
                .isDeleted(0)
                .expiredTime(expiredTime)
                .createTime(now.toString())
                .updateTime(now.toString())
                .value(vouchers).build();
        this.save(chartVouchers);
        return vouchers;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult verified(VerifiedReq req, String key) {
        String value = req.getValue();
        if (Objects.equals(value, "")) {
            return AjaxResult.error("兑换码不能为空");
        }
        ChartVouchers vouchers = this.getOne(Wrappers.<ChartVouchers>lambdaQuery()
                .eq(ChartVouchers::getValue, value)
                .eq(ChartVouchers::getStatus, 0));
        //if exist, used vouchers update user VIP status;
        if (Objects.isNull(vouchers)) {
            return AjaxResult.error("兑换码无效");
        }
        Integer months = VouchersType.parseValue(vouchers.getType());
        SysUserOrder userOrder = userOrderMapper.selectOne(Wrappers.<SysUserOrder>lambdaQuery()
                .eq(SysUserOrder::getUserId, req.getId()));
        //获取缓存
        LoginUser userInfo = SecurityUtils.getLoginUser();

        //如果对象不为空
        if (Objects.isNull(userOrder)) {
            SysUserOrder newUserOrder = new SysUserOrder();
            newUserOrder.setUserId(req.getId());
            LocalDateTime expiredTime = LocalDateTimeUtil.now().plusMonths(months);
            newUserOrder.setExpirationTime(expiredTime);
            newUserOrder.setRemark("兑换券" + req.getValue());
            userOrderMapper.insert(newUserOrder);
        } else {
            LocalDateTime expirationTime = userOrder.getExpirationTime();
            if (vouchers.getType() != 4) {
                LocalDateTime newExpired = expirationTime.plusMonths(months);
                userOrder.setExpirationTime(newExpired);
                userOrder.setRemark("兑换券:" + req.getValue());
                userOrderMapper.updateById(userOrder);
            }
        }

        Long userId = SecurityUtils.getUserId();
        if (userId == null) {
            return AjaxResult.success("获取用户id失败");
        }


        SysUser user = userMapper.selectUserById(req.getId());
        user.setIsVip(1);
        userMapper.updateById(user);
        vouchers.setStatus(1);
        vouchers.setUpdateTime(LocalDateTimeUtil.now().toString());
        vouchers.setUserId(userId);
        this.updateById(vouchers);
        //清楚用户缓存
        userInfo.setUser(user);
        redisCache.setCacheObject(key, userInfo, 30, TimeUnit.MINUTES);

        return AjaxResult.success("兑换成功,兑换时长:" + months + "月");
    }


    /**
     * 兑换码生成
     *
     * @return
     */
    private String vouchersGenerator() {
        return RandomStringUtils.randomAlphabetic(20);
    }
}
